home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Moscow ML 1.42 / src / toolssrc / Smltope.sml < prev   
Encoding:
Text File  |  1997-08-18  |  25.0 KB  |  698 lines  |  [TEXT/R*ch]

  1. (* Smltop.sml *)
  2.  
  3. open List Obj BasicIO Nonstdio;
  4. open Miscsys Memory Fnlib Config Mixture Const Smlexc Smlprim;
  5. open Globals Location Units Types Smlperv Code_dec Emitcode Emit_phr Compiler;
  6. open Symtable Patch;
  7. open Rtvals Load_phr Exec_phr;
  8.  
  9. exception Already of string
  10. and NotYet of string
  11.  
  12. fun add_suffix name suffix =
  13.   if Filename.check_suffix name suffix
  14.   then (Filename.chop_suffix name suffix, name)
  15.   else (name, name ^ suffix)
  16. ;
  17.  
  18. (* Loading in core a compiled bytecode file *)
  19.  
  20. fun tryEvalLoad name =
  21.   let
  22.     val (simplename, filename) = add_suffix name ".uo"
  23.     val uname = normalizedUnitName(Filename.basename simplename)
  24.     val () =
  25.       if member uname reservedUnitNames then
  26.         raise Fail ("load: cannot load built-in unit "^uname)
  27.       else ()
  28.     val () =
  29.       (ignore (Hasht.find (!watchDog) uname);
  30.        raise Already uname)
  31.       handle Subscript => ()
  32.     val block_len = ref 0
  33.     val code = ref ""
  34.     val truename = find_in_path filename
  35.     val is = open_in_bin truename
  36.     val () =
  37.       let
  38.         val stop = input_binary_int is
  39.         val start = pos_in is
  40.         val code_len = stop - start
  41.         val () = (block_len := code_len + 1)
  42.         (* Now we have to check, whether the unit body is compatible *)
  43.         (* with its compiled signature and previously loaded units. *)
  44.         val () = seek_in is stop
  45.         val tables = (input_value is : compiled_unit_tables)
  46.         val () =
  47.           Hasht.apply (fn uname' => fn stamp' =>
  48.               let val stamp'' = Hasht.find (!watchDog) uname' in
  49.                 if stamp'' <> stamp' then
  50.                   raise Fail ("load: compiled body of unit "^uname^
  51.                      " is incompatible with previously loaded unit "^
  52.                      uname')
  53.                 else ()
  54.               end
  55.               handle Subscript => raise NotYet uname')
  56.             (#cu_mentions tables)
  57.         (* The following line will cause the compiled signature *)
  58.         (* to be put into the current table of unit signatures (if not there)! *)
  59.         val sign = (Hasht.find (!currentSigTable) uname
  60.                    handle Subscript => readSig uname)
  61.         prim_val set_nth_char_ : string -> int -> char -> unit
  62.                                                  = 3 "set_nth_char"
  63.       in
  64.         if #cu_sig_stamp tables <> getOption (!(#uStamp sign)) then
  65.            raise Fail ("load: compiled body of unit "^uname^
  66.                        " is incompatible with its compiled signature")
  67.         else ();
  68.         seek_in is start;
  69.         code := static_alloc (!block_len);
  70.         fast_really_input is (!code) 0 code_len;
  71.         (* `set_nth_char' must not check the length of buff, *)
  72.         (* because `code' is allocated outside the heap! *)
  73.         set_nth_char_ (!code) code_len (Char.chr Opcodes.STOP);
  74.         app
  75.           (fn phr =>
  76.             patch_object (!code) ((#cph_pos phr) - start) (#cph_reloc phr))
  77.           (rev (#cu_phrase_index tables));
  78.         exportPublicNames uname
  79.           (#cu_exc_ren_list tables) (#cu_val_ren_list tables);
  80.         Hasht.insert (!currentSigTable) uname sign;
  81.         Hasht.insert (!watchDog) uname (#cu_sig_stamp tables);
  82.         close_in is
  83.       end
  84.       handle x =>
  85.         (close_in is; raise x)
  86.     val res = do_code false (!code) 0 (!block_len)
  87.   in () end
  88. ;
  89.  
  90. fun evalLoad s =
  91.   (catch_interrupt false; tryEvalLoad s; catch_interrupt true)
  92.   handle
  93.        SysErr(s, _) =>
  94.          (catch_interrupt true; raise Fail ("load: "^s))
  95.      | Already uname =>
  96.          (catch_interrupt true;
  97.           raise Fail ("load: unit "^uname^" has been loaded already"))
  98.      | NotYet uname =>
  99.          (catch_interrupt true;
  100.           raise Fail ("load: unit "^uname^" is needed but not yet loaded"))
  101.      | Out_of_memory =>
  102.          (catch_interrupt true; raise Fail "load: out of memory")
  103.      | Toplevel =>
  104.          (catch_interrupt true;
  105.           raise Fail "load: unable to load")
  106.      | x => (catch_interrupt true; raise x)
  107. ;
  108.  
  109. (* A more user-friendly load function:
  110.    * does not fail when a unit has already been loaded;
  111.    * automatically loads any unit that a requested unit depends on.
  112. *)
  113.  
  114. fun smartEvalLoad s =
  115.     let fun tryload s pending =
  116.         (catch_interrupt false; tryEvalLoad s; catch_interrupt true)
  117.         handle
  118.         SysErr(s, _) =>
  119.             (catch_interrupt true; raise Fail ("load: "^s))
  120.       | Already _ =>
  121.             catch_interrupt true
  122.       | NotYet missing =>
  123.             (catch_interrupt true;
  124.              if member missing pending then
  125.                  raise Fail ("load: unit " ^ missing ^
  126.                              " indirectly depends on itself")
  127.              else
  128.                  (tryload missing (s :: pending);
  129.                   tryload s pending))
  130.       | Out_of_memory =>
  131.             (catch_interrupt true; raise Fail "load: out of memory")
  132.       | Toplevel =>
  133.             (catch_interrupt true;
  134.              raise Fail "load: unable to load")
  135.       | x => (catch_interrupt true; raise x)
  136.     in tryload s [] end
  137. ;
  138.  
  139. fun protect_current_input fct =
  140.   let val saved_input_name = !input_name
  141.       and saved_input_stream = !input_stream
  142.       and saved_input_lexbuf = !input_lexbuf
  143.   in
  144.     (fct();
  145.      input_lexbuf := saved_input_lexbuf;
  146.      input_stream := saved_input_stream;
  147.      input_name := saved_input_name)
  148.     handle x =>
  149.       (input_lexbuf := saved_input_lexbuf;
  150.        input_stream := saved_input_stream;
  151.        input_name := saved_input_name;
  152.        raise x)
  153.   end
  154. ;
  155.  
  156. (* Loading an SML source file *)
  157.  
  158. fun loadToplevelPhrase lexbuf =
  159.   let val (phrase, isLast) = parseToplevelPhrase lexbuf in
  160.     execToplevelPhrase phrase;
  161.     isLast
  162.   end
  163. ;
  164.  
  165. fun evalUse filename =
  166.   let
  167.     val truename =
  168.       (find_in_path filename
  169.        handle Fail msg =>
  170.          (msgIBlock 0; errPrompt msg; msgEOL(); msgEBlock(); msgFlush();
  171.           raise Toplevel))
  172.     val () = (msgIBlock 0;
  173.               msgString "[opening file \""; msgString truename;
  174.               msgString "\"]"; msgEOL(); msgEBlock(); msgFlush())
  175.     val is = open_in_bin truename
  176.     val lexbuf = Compiler.createLexerStream is
  177.     fun closeIn() =
  178.       (close_in is;
  179.        msgIBlock 0;
  180.        msgString "[closing file \""; msgString truename;
  181.        msgString "\"]"; msgEOL(); msgEBlock(); msgFlush())
  182.   in
  183.     ( protect_current_input (fn () =>
  184.         (input_name := truename;
  185.          input_stream := is;
  186.          input_lexbuf := lexbuf;
  187.          while true do
  188.            let val isLast = loadToplevelPhrase lexbuf
  189.            in if isLast then raise EndOfFile else () end)))
  190.     handle
  191.         EndOfFile => closeIn()
  192.       | x => (closeIn(); raise x)
  193.   end
  194. ;
  195.  
  196. (* Compile a file *)
  197.  
  198. fun tryEvalCompile s =
  199.   protect_current_input (fn () => protectCurrentUnit (fn () =>
  200.     if Filename.check_suffix s ".sig" then
  201.       let val filename = Filename.chop_suffix s ".sig" in
  202.         compileSignature
  203.           (normalizedUnitName (Filename.basename filename))
  204.           filename
  205.       end
  206.     else if Filename.check_suffix s ".sml" then
  207.       let val filename = Filename.chop_suffix s ".sml" in
  208.         compileUnitBody
  209.           (normalizedUnitName (Filename.basename filename))
  210.           filename
  211.       end
  212.     else
  213.       raise Fail "compile: unknown file name extension"))
  214. ;
  215.  
  216. fun evalCompile s =
  217.   tryEvalCompile s
  218.   handle
  219.        Interrupt => raise Fail "compile: interrupted by the user"
  220.      | Out_of_memory => raise Fail "compile: out of memory"
  221.      | Toplevel => raise Fail "compile: error(s) in the source program"
  222. ;
  223.  
  224. (* ****************************************************** *)
  225.  
  226. (* Make.sml *)
  227. (* 05Sep95 e *)
  228.  
  229. (* portions stolen from... *)
  230.  
  231. (* Mosmldep -- computing dependencies in a Moscow ML source directory. *)
  232.  
  233. (* Lexer of stream *)
  234.  
  235. fun createLexerStream (is : instream) =
  236.   Lexing.createLexer (fn buff => fn n => Nonstdio.buff_input is buff 0 n)
  237. ;
  238.  
  239. fun parsePhraseAndClear parsingFun lexingFun lexbuf =
  240.   let val phr =
  241.     parsingFun lexingFun lexbuf
  242.     handle x => (Parsing.clearParser(); raise x)
  243.   in
  244.     Parsing.clearParser();
  245.     phr
  246.   end;
  247.  
  248. val parseFile =
  249.   parsePhraseAndClear Deppars.MLtext Deplex.Token;
  250.  
  251. fun addExt s ext = s ^ "." ^ ext;
  252.  
  253. (* now the new stuff... *)
  254.  
  255. (* 1- use Mosmldep to find each source file's dependencies
  256.    2- build some data structures (see below)
  257.    3- make the transitive closure of the dependencies
  258.    4- sort the files in dependency order
  259.    5- process each file in turn
  260.         checking modified times as documented below for function ensure
  261.         and compiling out-of-date files
  262.  
  263.   data structures...
  264.   after parsing: (objname,srcname,[objdeps],[moddeps]) called pd
  265.   closedeps calls pdltoa to make...
  266.   a hash table:   objname -> index                     called hn
  267.   and an array:   index -> pd                          called ap
  268.   and an array:   index -> [indexes of objdeps]        called di
  269.   closedeps makes
  270.       an array of indexes in dependency sorted order   called oi
  271.    and returns the value (n,hn,ap,di,oi)
  272.    where n is the length of the arrays
  273.   ensure uses n,hn,ap,di,oi to compile files needing it
  274.  
  275.   pd
  276.       objname is the name of the object file
  277.         .sml files generate .uo entry
  278.         .sig files generate .ui entry
  279.       srcname is the name of the file found in the directory
  280.       objdeps is a list of object files depended upon
  281.         dependency on a unit inserts
  282.           <unit>.ui into deps if <unit>.sig exists
  283.           otherwise <unit>.uo is inserted
  284.       moddeps is a list of units (not in this directory) depended upon
  285.  
  286.   read (the file parser) keeps a hash table of previously generated pd
  287.    it is keyed by srcname;
  288.    the modTime of the file is kept and checked to insure accuracy
  289.    this hashtable can be manually cleared with: reset_readht();
  290. *)
  291.  
  292. val moolevel = ref 1;
  293.  
  294. (* moolevel
  295. 0: no messages
  296. 1: error messages
  297. 2: compile messages
  298. 3: progress messages
  299. *)
  300.  
  301. fun moo v s1 s2 = if !moolevel >= v then (print s1; print s2; print "\n") else ();
  302. fun muu v s     = if !moolevel >= v then  print s                     else ();
  303.  
  304. fun pdltoa pdl =
  305.   let val hn = Hasht.new 37 : (string, int) Hasht.t
  306.       fun lp1 n r =
  307.         if (null r) then n
  308.         else let val (name,_,_,_) = (hd r)
  309.              in Hasht.insert hn name n;
  310.                 lp1 (n+1) (tl r)
  311.              end
  312.   in 
  313.     let val q  = lp1 0 pdl
  314.         val ap = Array.array(q,("","",[""],[""]))
  315.         val di = Array.array(q,[])
  316.         fun lp2 n r =
  317.           if (null r) then ()
  318.           else let val (name,_,ns,_) = (hd r)
  319.                in Array.update(ap,n,(hd r));
  320.                   Array.update(di,n,(List.map (Hasht.find hn) ns));
  321.                   lp2 (n+1) (tl r)
  322.                end
  323.     in
  324.       lp2 0 pdl;
  325.       (q,hn,ap,di)
  326.     end
  327.   end;
  328.  
  329. fun closedeps pdl =
  330.   let val (n,hn,ap,di) = pdltoa pdl
  331.       val dp = Array.array (n, []) (* dependents *)
  332.       val qd = Array.array (n, 0 ) (* dependencies *)
  333.       fun initdeps (deps,x) =
  334.         let fun idep m r =
  335.               if (null r) then m
  336.               else let val h = hd r
  337.                    in Array.update ( dp, h, x :: (Array.sub (dp, h)) );
  338.                       idep (m + 1) (tl r)
  339.                    end
  340.         in Array.update (qd, x, idep 0 deps);
  341.            x+1
  342.         end
  343.       val oi = Array.array (n, 0 )
  344.       val qi = ref 0 (* queue in *)
  345.       val ou = ref 0 (* queue out *)
  346.       fun enque x = (Array.update ( oi, !qi, x ); qi := !qi + 1)
  347.       fun pass1 i =
  348.         if (i = n) then ()
  349.         else let val x = Array.sub (qd, i)
  350.              in if ( x = 0 ) then enque i else ();
  351.                 pass1 (i + 1 )
  352.              end
  353.       fun pass2 r =
  354.         if (null r) then ()
  355.         else let val h = hd r
  356.                  val x = Array.sub (qd, h) - 1
  357.              in Array.update ( qd, h, x );
  358.                 if ( x = 0 ) then enque h else ();
  359.                 pass2 (tl r)
  360.              end
  361.       fun deque x = (pass2 (Array.sub (dp, x)); ou := !ou + 1)
  362.   in
  363.     moo 3 "\n" "Computing Dependencies";
  364.     Array.foldl initdeps 0 di;
  365.     pass1 0;
  366.     while ( !ou < !qi ) do deque (Array.sub (oi, !ou));
  367.     if (!ou = n)
  368.     then ()
  369.     else let val (nm,_,_,_) = Array.sub (ap,!ou)
  370.          in moo 1 "Circularity involving: "  nm;
  371.             raise (Fail "circle"); () 
  372.          end;
  373.     (n,hn,ap,di,oi)
  374.   end;
  375.  
  376. fun read' pdl srcext objext filename =
  377.   let val is       = open_in (addExt filename srcext)
  378.       val lexbuf   = createLexerStream is
  379.       val mentions = Hasht.new 37 : (string, unit) Hasht.t
  380.       val names    = parseFile lexbuf
  381.       val objlist = ref []
  382.       val modlist = ref []
  383.       fun adddep s =
  384.             if FileSys.access (addExt s "sig", []) then
  385.               objlist := addExt s "ui" :: !objlist
  386.             else if FileSys.access (addExt s "sml", []) then
  387.               objlist := addExt s "uo" :: !objlist
  388.         else (* libr or included dir files? *)
  389.           modlist := s :: !modlist
  390.   in 
  391.     close_in is;
  392.     List.app (fn name => Hasht.insert mentions name ()) names;
  393.     if srcext = "sml" andalso FileSys.access(addExt filename "sig", [])
  394.         then Hasht.insert mentions filename () else ();
  395.     Hasht.apply (fn name => fn _ => adddep name) mentions;
  396.     pdl := ((addExt filename objext),
  397.             (addExt filename srcext),
  398.             !objlist,
  399.             !modlist) :: !pdl
  400.   end
  401.   handle Parsing.ParseError _ => output(std_out, "Parseerror!\n");
  402.  
  403. val readht = ref (Hasht.new 67
  404.                   : (string, (Time.time *
  405.                               (string * string * string list * string list)))
  406.                   Hasht.t);
  407.  
  408. fun reset_readht _ =
  409.        readht := (Hasht.new 67
  410.                   : (string, (Time.time *
  411.                               (string * string * string list * string list)))
  412.                   Hasht.t);
  413.  
  414. fun read pdl srcext objext filename =
  415.   let val sn = (addExt filename srcext)
  416.       val mt = FileSys.modTime sn
  417.       fun dit s = muu 3 s
  418.       fun oops s =
  419.          ( dit s;
  420.            read' pdl srcext objext filename;
  421.            Hasht.insert (!readht) sn (mt,(hd (!pdl))) )
  422.   in
  423.     let val (tm,pd) = Hasht.find (!readht) sn
  424.     in
  425.       case (Time.compare (tm,mt)) of
  426.          EQUAL => ( dit "."; pdl := pd :: !pdl )
  427.        | _     => oops ";"
  428.     end
  429.     handle _ => oops ":"
  430.   end;
  431.  
  432. fun checkf srcext genext base =
  433.   let val gennam = (addExt base genext)
  434.       val havgen = (FileSys.access (gennam,[]))
  435.   in
  436.     if havgen then ()
  437.     else moo 2 "  warning: " ((addExt base srcext) ^ " but no: " ^ gennam)
  438.   end;
  439.  
  440. fun processfile pdl filename =
  441.   let val {base, ext} = Path.splitBaseExt filename
  442.       val base' = Path.file base
  443.   in 
  444.         case ext of
  445.             SOME "sig" =>  read pdl "sig" "ui" base'
  446.           | SOME "sml" =>  read pdl "sml" "uo" base'
  447.           | SOME "grm" => (checkf "grm" "sml" base'; checkf "grm" "sig" base')
  448.           | SOME "lex" =>  checkf "lex" "sml" base'
  449.           | SOME "mlp" =>  checkf "mlp" "sml" base'
  450.           | _          =>  ()
  451.   end;
  452.  
  453. fun perv_set set =
  454.   (preloadedUnits := Fnlib.lookup set preloadedUnitSets;
  455.    preopenedPreloadedUnits := Fnlib.lookup set preopenedPreloadedUnitSets)
  456.   handle Subscript =>
  457.     raise (Fail ("Unknown preloaded unit set " ^ set))
  458.  
  459. fun protect_current_options fct =
  460.   let val saved_path_library     = !path_library
  461.       and saved_load_path        = !load_path
  462.       and saved_preloadedUnits   = !preloadedUnits
  463.       and saved_poPreloadedUnits = !preopenedPreloadedUnits
  464.       and saved_watchDog         = !watchDog
  465.   (*  and saved_verbose          = !Compiler.verbose
  466.       and saved_quotation        = !Lexer.quotation     *)
  467.       and saved_autolink         = !Link.autolink
  468.       and saved_write_symbols    = !Link.write_symbols
  469.       and saved_no_header        = !Link.no_header
  470.   in
  471.     (fct();
  472.      path_library            := saved_path_library;
  473.      load_path               := saved_load_path;
  474.      preloadedUnits          := saved_preloadedUnits;
  475.      preopenedPreloadedUnits := saved_poPreloadedUnits;
  476.      watchDog                := saved_watchDog;
  477.   (* Compiler.verbose        := saved_verbose;
  478.      Lexer.quotation         := saved_quotation;        *)
  479.      Link.autolink           := saved_autolink;
  480.      Link.write_symbols      := saved_write_symbols;
  481.      Link.no_header          := saved_no_header
  482.      )
  483.     handle x =>
  484.       (path_library            := saved_path_library;
  485.        load_path               := saved_load_path;
  486.        preloadedUnits          := saved_preloadedUnits;
  487.        preopenedPreloadedUnits := saved_poPreloadedUnits;
  488.        watchDog                := saved_watchDog;
  489.   (*   Compiler.verbose        := saved_verbose;
  490.        Lexer.quotation         := saved_quotation;      *)
  491.        Link.autolink           := saved_autolink;
  492.        Link.write_symbols      := saved_write_symbols;
  493.        Link.no_header          := saved_no_header;
  494.        raise x)
  495.   end
  496.  
  497. (* ensure -- that a file is compiled if need be
  498.    1- if there is no object
  499.    2- if the mtime of the object is older than the epoch
  500.    3- if the mtime of the source is newer than mtime of the object
  501.    4- if the mtime of any dependency is newer than the mtime of the object
  502.    
  503.    the build order of the files is passed in oi
  504.    trick: we keep the mtime of each object in an array, timarr, indexed
  505.           by position in the initial list; since only files earlier in
  506.           the list can be depended upon, only their times are needed, so
  507.           mtimes of files are thereby memoized
  508.    dependencies on units outside the target directory are also checked
  509.     and memoized in a local hashtable
  510. *)
  511.  
  512. fun ensure epoch (n,hn,ap,di,oi) =
  513.   let val timarr = Array.array(n,Time.zeroTime)
  514.       fun ftime x = Array.sub(timarr,x)
  515.       val itimes = Hasht.new 37 : (string, Time.time) Hasht.t
  516.       fun itime' m = 
  517.         let val uiname = (addExt m "ui")
  518.             val prname = find_in_path uiname
  519.         in moo 3 " checking: "  m;
  520.            FileSys.modTime prname
  521.         end handle Fail s => (moo 1 "  uncheck: " s; epoch)
  522.       fun itime m = Hasht.find itimes m
  523.                     handle Subscript =>
  524.                       let val i = itime' m  (* memoize! *)
  525.                       in Hasht.insert itimes m i; i end
  526.       fun nxt z =
  527.         if z >= n then ()
  528.         else let val x = Array.sub(oi,z)
  529.                  val (objname,srcname,objdeps,moddeps) = Array.sub(ap,x)
  530.                  val deps = Array.sub (di,x)
  531.              in
  532.                 if( FileSys.access (objname,[]) andalso
  533.                     let val otime = FileSys.modTime objname in
  534.                       Time.>(otime,epoch) andalso
  535.                       Time.>(otime,(FileSys.modTime srcname)) andalso
  536.                       (* this is conservative; too conservative if make is always used!
  537.                       (List.all (fn d => Time.>(otime,ftime d)) deps) andalso
  538.                       *)
  539.                       (List.all (fn d => Time.>=(otime,ftime d)) deps) andalso
  540.                       (List.all (fn d => Time.>(otime,itime d)) moddeps) andalso
  541.                       ( Array.update(timarr,x,otime); true )
  542.                     end )
  543.                 then moo 3 " ensuring: " objname
  544.                 else ( moo 2 "compiling: " objname;
  545.                        evalCompile srcname;
  546.                        Array.update(timarr,x,FileSys.modTime objname) );
  547.                 nxt (z+1)
  548.              end
  549.   in nxt 0;
  550.      moo 3 "" ""
  551.   end;
  552.  
  553. fun make oset stdlib includes path =
  554.   let open FileSys
  555.       val _   = if !moolevel < 0  (* kludgy way to reset table *)
  556.                 then (reset_readht(); moolevel := (~ (!moolevel)))
  557.                 else ()
  558.       val pdl = ref []
  559.       val dir = openDir path
  560.       val _   =   chDir path
  561.       fun read "" = ()
  562.         | read f  = ( processfile pdl f ; read (readDir dir) )
  563.       val _ = ( read (readDir dir); closeDir dir; () )
  564.               handle exn as OS.SysErr (msg, _) => (moo 1 msg ""; raise exn)
  565.       val nhnapdioi = closedeps (!pdl)
  566.   in
  567.     protect_current_options (fn () =>
  568.       (path_library := stdlib;
  569.        load_path := (if stdlib <> ""
  570.                      then includes @ [stdlib]
  571.                      else includes);
  572.        perv_set (if oset <> "" then oset else "default");
  573.        ensure Time.zeroTime nhnapdioi
  574.       ))
  575.   end;
  576.  
  577. (* new link interface 24Jul97 e *)
  578.  
  579. fun lynk exec_file (gopt,hopt) (auto,oset) stdlib includes files =
  580.   protect_current_options (fn () => (protect_linker_tables (fn () =>
  581.      (path_library := stdlib;
  582.       load_path := (if stdlib <> "" then includes @ [stdlib] else includes);
  583.       let val fi = ref files
  584.       in
  585.         if auto
  586.         then ()
  587.         else ( perv_set (case oset of "" => "default" | _ => oset );
  588.                fi := (map (fn un => un ^".uo") (!preloadedUnits)) @ (!fi) );
  589.         Link.autolink       := auto;
  590.         Link.no_header      := hopt;
  591.         Link.write_symbols  := gopt;
  592.         reset_linker_tables();
  593.         watchDog := (Hasht.new 17 : (string, SigStamp) Hasht.t);
  594.         Link.link (!fi) exec_file;
  595.         ()
  596.       end))));
  597.  
  598. (* ****************************************************** *)
  599.  
  600. val smltop_con_basis =
  601. [
  602.   ("use",    { qualid={qual="Meta", id="use"},       info=VARname REGULARo}),
  603.   ("load",   { qualid={qual="Meta", id="load"},      info=VARname REGULARo}),
  604.   ("loadOne",{ qualid={qual="Meta", id="loadOne"},   info=VARname REGULARo}),
  605.   ("compile",{ qualid={qual="Meta", id="compile"},   info=VARname REGULARo}),
  606.   ("verbose",{ qualid={qual="Meta", id="verbose"},   info=VARname REGULARo}),
  607.   ("quotation",
  608.              { qualid={qual="Meta", id="quotation"}, info=VARname REGULARo}),
  609.   ("valuepoly",
  610.              { qualid={qual="Meta", id="valuepoly"}, info=VARname REGULARo}),
  611.   ("exnName",
  612.              { qualid={qual="Meta", id="exnName"},   info=VARname REGULARo}),
  613.   ("exnMessage",
  614.              { qualid={qual="Meta", id="exnMessage"},info=VARname REGULARo}),
  615.   ("printVal", { qualid={qual="Meta", id="printVal"},info=VARname OVL1TXXo}),
  616.   ("printDepth",
  617.              { qualid={qual="Meta", id="printDepth"},info=VARname REGULARo}),
  618.   ("printLength",
  619.              { qualid={qual="Meta", id="printLength"}, info=VARname REGULARo}),
  620.   ("chDir",  { qualid={qual="Meta", id="chDir"},     info=VARname REGULARo}), (* e *)
  621.  ("moolevel",{ qualid={qual="Meta", id="moolevel"},  info=VARname REGULARo}), (* e *)
  622.   ("make",   { qualid={qual="Meta", id="make"},      info=VARname REGULARo}), (* e *)
  623.   ("link",   { qualid={qual="Meta", id="link"},      info=VARname REGULARo}), (* e *)
  624.   ("system", { qualid={qual="Meta", id="system"},
  625.                info=PRIMname (mkPrimInfo 1 (MLPccall(1, "sml_system"))) }),
  626.   ("quit",   { qualid={qual="Meta", id="quit"},    info=VARname REGULARo}),
  627.   ("installPP",
  628.              { qualid={qual="Meta", id="installPP"}, info=VARname OVL1TPUo})
  629. ];
  630.  
  631. val smltop_VE =
  632. [
  633.    ("use",         trivial_scheme(type_arrow type_string type_unit)),
  634.    ("load",        trivial_scheme(type_arrow type_string type_unit)),
  635.    ("loadOne",     trivial_scheme(type_arrow type_string type_unit)),
  636.    ("compile",     trivial_scheme(type_arrow type_string type_unit)),
  637.    ("verbose",     trivial_scheme(type_ref type_bool)),
  638.    ("quotation",   trivial_scheme(type_ref type_bool)),
  639.    ("valuepoly",   trivial_scheme(type_ref type_bool)),
  640.    ("exnName",     trivial_scheme (type_arrow type_exn type_string)),
  641.    ("exnMessage",  trivial_scheme (type_arrow type_exn type_string)),
  642.    ("printDepth",  trivial_scheme (type_ref type_int)),
  643.    ("printLength", trivial_scheme (type_ref type_int)),
  644.    ("chDir",       trivial_scheme(type_arrow type_string type_unit)), (* e *)
  645.    ("moolevel",    trivial_scheme (type_ref type_int)),               (* e *)
  646.    ("make",        trivial_scheme(type_arrow type_string              (* e *)
  647.                                    (type_arrow type_string
  648.                                    (type_arrow (type_list type_string)
  649.                                    (type_arrow type_string type_unit))))),
  650.    ("link",        trivial_scheme(type_arrow type_string              (* e *)
  651.                                    (type_arrow (type_pair type_bool type_bool)
  652.                                    (type_arrow (type_pair type_bool type_string)
  653.                                    (type_arrow type_string
  654.                                    (type_arrow (type_list type_string)
  655.                                    (type_arrow (type_list type_string) type_unit))))))),
  656.    ("system",      trivial_scheme(type_arrow type_string type_int)),
  657.    ("quit",        trivial_scheme(type_arrow type_unit type_unit))
  658. ];
  659.  
  660. val unit_smltop = newSig "Meta";
  661.  
  662. val () =
  663.   app
  664.     (fn (id, status) => Hasht.insert (#uConBasis unit_smltop) id status)
  665.     smltop_con_basis
  666. ;
  667.  
  668. val () =
  669.   app
  670.     (fn (id, sc) => Hasht.insert (#uVarEnv unit_smltop) id sc)
  671.     smltop_VE
  672. ;
  673.  
  674. val () = Hasht.insert pervSigTable "Meta" unit_smltop;
  675.  
  676. fun resetSMLTopDynEnv() =
  677.   loadGlobalDynEnv "Meta" [
  678.     ("use",         repr (evalUse: string -> unit)),
  679.     ("loadOne",     repr evalLoad),
  680.     ("load",        repr smartEvalLoad),
  681.     ("compile",     repr evalCompile),
  682.     ("verbose",     repr verbose),
  683.     ("quotation",   repr Lexer.quotation),
  684.     ("valuepoly",   repr Mixture.value_polymorphism),
  685.     ("printVal",    repr evalPrint),
  686.     ("exnName",     repr Rtvals.getExnName),
  687.     ("exnMessage",  repr Rtvals.getExnMessage),
  688.     ("printDepth",  repr printDepth),
  689.     ("printLength", repr printLength),
  690.     ("chDir",       repr (fn n => FileSys.chDir n)), (* e *)
  691.     ("moolevel",    repr moolevel),                  (* e *)
  692.     ("make",        repr make),                      (* e *)
  693.     ("link",        repr lynk),                      (* e *)
  694.     ("quit",        repr (fn () => (msgFlush(); BasicIO.exit 0))),
  695.     ("installPP",   repr evalInstallPP)
  696. ];
  697.  
  698.